package com.qidi.mvcframework.servlet.support;

import com.qidi.mvcframework.servlet.annotation.MyService;
import com.qidi.mvcframework.servlet.beans.config.MyBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class MyBeanDefinitionReader {

    // 配置信息
    private Properties contextConfig = new Properties();

    // 扫描到的全类名 原来的 classNames
    private List<String> registryBeanClasses = new ArrayList<>();

    public MyBeanDefinitionReader(String... configLocations) {
        // 加载配置文件
        doLoadConfig(configLocations[0]);
        // 扫描类
        doScanner(contextConfig.getProperty("scanPackage"));
    }

    public Properties getConfig() {
        return this.contextConfig;
    }

    public List<MyBeanDefinition> loadBeanDefinitions() {
        List<MyBeanDefinition> result = new ArrayList<>();
        try {
            for (String className : registryBeanClasses) {
                Class<?> beanClass = Class.forName(className);
                if (beanClass.isInterface()) continue;
                // 保存类对应的全类名 和 beanName
                // beanName 有 3 种：
                // 1 默认类名首字母小写
                String beanName = toLowerFirstCase(beanClass.getSimpleName());
                // 2 自定义
                if (beanClass.isAnnotationPresent(MyService.class)) {
                    String value = beanClass.getAnnotation(MyService.class).value();
                    if (!"".equals(value.trim())) beanName = value;
                }
                result.add(doCreateBeanDefinition(beanName, beanClass.getName()));
                // 3 接口注入
                for (Class<?> i : beanClass.getInterfaces()) {
                    result.add(doCreateBeanDefinition(i.getName(), beanClass.getName()));
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return result;
    }

    private MyBeanDefinition doCreateBeanDefinition(String beanName, String beanClassName) {
        MyBeanDefinition beanDefinition = new MyBeanDefinition();
        beanDefinition.setFactoryBeanName(beanName);
        beanDefinition.setBeanClassName(beanClassName);
        return beanDefinition;
    }

    private String toLowerFirstCase(String simpleName) {
        char[] chars = simpleName.toCharArray();
        chars[0] += 32;
        return new String(chars);
    }

    private void doLoadConfig(String contextConfigLocation) {
        try (
                // 获取到 application.properties 文件流
                // <param-value>classpath:application.properties</param-value>
                InputStream is = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation.replaceAll("classpath:", ""))
        ) {
            contextConfig.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void doScanner(String scanPackage) {
        // 扫描路径
        URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));

        File classPath = new File(url.getFile());

        for (File file : classPath.listFiles()) {
            if (file.isDirectory()) {
                doScanner(scanPackage + "." + file.getName());
            } else {
                if (!file.getName().endsWith(".class")) continue;
                // 截取全类名，防止有不同包的同名类
                String className = scanPackage + "." + file.getName().replace(".class", "");
                // 保存
                registryBeanClasses.add(className);
            }
        }
    }

}
